package com.sangengblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sangengblog.constants.SystemConstants;
import com.sangengblog.domain.ResponseResult;
import com.sangengblog.domain.entity.Menu;
import com.sangengblog.domain.vo.MenuTreeVo;
import com.sangengblog.domain.vo.MenuVo;
import com.sangengblog.enums.AppHttpCodeEnum;
import com.sangengblog.mapper.MenuMapper;
import com.sangengblog.service.MenuService;
import com.sangengblog.utils.BeanCopyUtils;
import com.sangengblog.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static io.lettuce.core.GeoArgs.Unit.m;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2024-04-10 21:53:41
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {


    @Override
    public List<String> selectPermsByUserId(Long id) {
        //如果是管理员，返回所有权限
        if (id == 1L || id == 2L) {
            LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Menu::getMenuType, SystemConstants.MENU, SystemConstants.BUTTON);
            wrapper.eq(Menu::getStatus, SystemConstants.STATUS_NORMAL);
            List<Menu> menus = list(wrapper);
            List<String> perms = menus.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            System.out.println(perms);
            return perms;
        }
        //否则返回所具有的权限
        return getBaseMapper().selectPermsByUserId(id);
    }

    @Override
    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是管理员
        if (SecurityUtils.isAdmin()) {
            //如果是 获取所有符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();
        } else {
            //否则  获取当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }

        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<Menu> menuTree = builderMenuTree(menus, 0L);
        return menuTree;
    }

    @Override
    public ResponseResult list(String status, String menuName) {
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(status), Menu::getStatus, status);
        wrapper.like(StringUtils.hasText(menuName), Menu::getMenuName, menuName);
        wrapper.orderByAsc(Menu::getOrderNum);
        wrapper.orderByAsc(Menu::getParentId);
        List<Menu> menus = list(wrapper);
        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menus, MenuVo.class);
        return ResponseResult.okResult(menuVos);
    }

    @Override
    public ResponseResult add(Menu menu) {
        save(menu);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getMenuInfo(Long id) {
        Menu menu = getById(id);
        MenuVo menuVo = BeanCopyUtils.copyBean(menu, MenuVo.class);
        return ResponseResult.okResult(menuVo);
    }

    @Override
    public ResponseResult updateMenu(Menu menu) {
        if (menu.getId().equals(menu.getParentId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "不能选择自己作为父级菜单");
        }
        LambdaUpdateWrapper<Menu> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Menu::getId, menu.getId());
        update(menu, updateWrapper);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteMenu(Long menuId) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId, menuId);
        if (!list(queryWrapper).isEmpty()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "存在子菜单不允许删除");
        }
        LambdaUpdateWrapper<Menu> updateWrapper = new LambdaUpdateWrapper<Menu>().eq(Menu::getId, menuId).set(Menu::getDelFlag, "1");
        update(updateWrapper);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult treeSelect() {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Menu::getOrderNum);
        List<Menu> menus = list(queryWrapper);

        List<MenuTreeVo> menuTree = getMenuTreeSetLabel(menus);
//        List<MenuTreeVo> menuTreeVos = menus.stream().map(m -> new MenuTreeVo(m.getId(), m.getMenuName(), m.getParentId(), null)).collect(Collectors.toList());
//        List<MenuTreeVo> menuTree = menuTreeVos.stream().filter(m -> m.getParentId().equals(0L))
//                .map(m -> m.setChildren(getChildList(m, menuTreeVos)))
//                .collect(Collectors.toList());

        return ResponseResult.okResult(menuTree);
    }

    @Override
    public ResponseResult roleMenuTreeSelect(Long id) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = menuMapper.selectAllRouterMenu();
        List<Long> menuIds = null;
        if (id == 1L) {
            menuIds = menuMapper.selectAllRouterMenu().stream().map(Menu::getId).collect(Collectors.toList());
        } else {
            menuIds = menuMapper.selectMenuIdsByRoleId(id);
        }

        List<MenuTreeVo> menuTree = getMenuTreeSetLabel(menus);
//        List<MenuTreeVo> menuTreeVos = menus.stream().map(m -> new MenuTreeVo(m.getId(), m.getMenuName(), m.getParentId(), null)).collect(Collectors.toList());
//        List<MenuTreeVo> menuTree = menuTreeVos.stream().filter(m -> m.getParentId().equals(0L))
//                .map(m -> m.setChildren(getChildList(m, menuTreeVos)))
//                .collect(Collectors.toList());

        HashMap<String, Object> map = new HashMap<>();
        map.put("menus", menuTree);
        map.put("checkedKeys", menuIds);
        return ResponseResult.okResult(map);
    }

    /*
     * 处理前端菜单名称字段为label获取menuTree的子菜单
     */
    private List<MenuTreeVo> getChildList(MenuTreeVo menuTreeVo, List<MenuTreeVo> menuTreeVos) {
        List<MenuTreeVo> children = menuTreeVos.stream().filter(m -> m.getParentId().equals(menuTreeVo.getId())).collect(Collectors.toList());
        return children;
    }

    /*
     * 处理前端菜单名称字段为label获取menuTree
     */
    private List<MenuTreeVo> getMenuTreeSetLabel(List<Menu> menus){
        List<MenuTreeVo> menuTreeVos = menus.stream().map(m -> new MenuTreeVo(m.getId(), m.getMenuName(), m.getParentId(), null)).collect(Collectors.toList());
        List<MenuTreeVo> menuTree = menuTreeVos.stream().filter(m -> m.getParentId().equals(0L))
                .map(m -> m.setChildren(getChildList(m, menuTreeVos)))
                .collect(Collectors.toList());
        return menuTree;
    }


    private List<Menu> builderMenuTree(List<Menu> menus, Long parentId) {
        List<Menu> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren(menu, menus)))
                .collect(Collectors.toList());
        return menuTree;
    }

    /**
     * 获取存入参数的 子Menu集合
     *
     * @param menu
     * @param menus
     * @return
     */
    private List<Menu> getChildren(Menu menu, List<Menu> menus) {
        List<Menu> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m -> m.setChildren(getChildren(m, menus)))
                .collect(Collectors.toList());
        return childrenList;
    }

}
